package Cluedo.GUI;

import Cluedo.API.Message;
import Cluedo.API.StringFuncs;
import Cluedo.API.CluedoConfig;
import java.util.Vector;
import java.util.StringTokenizer;


/**
 * Reponsible for acting on parsed messages (usually from the command line).
 *
 * @author Alex Ellis
 */
public class TextEventHandler { 

   // Which View this is handling input for
   Object parent = null;
   
   
   public TextEventHandler(Object newParent){
   	parent = newParent;
   }
   
   /**
    * Sends a message to all bound listeners.
    * 
    * @param message
    */
   void notifyListener(Cluedo.API.Message message) {
   	try {

   		if(parent instanceof Cluedo.GUI.Simple)
   			((Cluedo.API.CluedoListener)((Simple)parent).getCluedoListener()).localMessage(message);
   		else if(parent instanceof Cluedo.API.CluedoGUIListener)
   			((Cluedo.API.CluedoGUIListener)parent).localMessage(message);
   	}
   	catch(Exception error) {
   		System.out.println("[TextEventHandler:notifyListener] can't notify listener");
   	}

   }

  /**
  * Calls events in its parent according to the parsed information. All
  * information typed on the console in the GUI passes through here, providing
  * it was a valid command in the set of commands in the parser.
  * @param parsedData
  *        an array of strings
  * @return reponse string, often not always necessary
  */
  public void handleCommandLine(String [] parsedData) {
		Message message = new Message();
		CluedoConfig gameConfig = null; 

		if(parent instanceof Simple)
			gameConfig = ((Simple)parent).getGameConfig();

		boolean formingGame;
		boolean disproveMode;

		formingGame = gameConfig.isFormingGame();
		disproveMode = gameConfig.inDisproveMode();
		
		try {
			if(disproveMode == false &&  formingGame == false) {
	      			if(parsedData.length == 1) {
	      				// Quit
	      				if(parsedData[0].equals("quit")) {
	      					message.type = "quit";
	     				}
	      				if(parsedData[0].equals("instructions")) {
	      					message.type = "showInstructionsFile";
	     				}
	      				// Newgame
	      				if(parsedData[0].equals("startgame")) {
	      					message.type = "formingNewGame";
	     				}
	      				if(parsedData[0].equals("help"))
	      					message.type = "showHelpFile";
	      				if(parsedData[0].equals("roll")) {
	      					message.type = "gameAction";
	      					message.data = "roll";
	      				}
	      				if(parsedData[0].equals("info")) {
	      					message.type = "gameAction";
	      					message.data = "info";
	      				}
	      				if(parsedData[0].equals("showcards")) {
	      					message.type = "gameAction";
	      					message.data = "show cards";
	      				}
	      				if(parsedData[0].equals("positions")) {
	      					message.type = "gameAction";
	      					message.data = "positions";
	      				}
	      				
      				
	      			}
				if(parsedData.length == 2) {
	      				if(parsedData[0].equals("roll")) {
						if(parsedData[1].equals("dice")) {
				      			message.type = "gameAction";
				      			message.data = "roll";
						}
	      				}
      					if(parsedData[0].equals("unmark")) {
							message.type = "gameAction";
							message.data = "uneliminate card";
							message.parameters.add(parsedData[1]);
      					}
      					else if(parsedData[0].equals("mark")) {
							message.type = "gameAction";
							message.data = "eliminate card";
							message.parameters.add(parsedData[1]);
      					}
      					else if(parsedData[0].equals("eliminate")) {
							message.type = "gameAction";
							message.data = "eliminate card";
							message.parameters.add(parsedData[1]);
					}
      					else if(parsedData[0].equals("load")) {
							message.type = "loadGame";
							message.parameters.add(parsedData[1]);
      					}
      					else if(parsedData[0].equals("save")) {
							message.type = "saveGame";
							message.parameters.add(parsedData[1]);
      					}
      					else if(parsedData[0].equals("saves")) {
							message.type = "saveGames";
							message.parameters.add(parsedData[1]);
      					}
					else if(parsedData[0].equals("script")) {
						message.type = "loadScript";
						message.parameters.add(parsedData[1]);
					}
					else if(parsedData[0].equals("move")) {
						message.type = "gameAction";
						message.data = "movePlayer";
						message.parameters.add(parsedData[1]);
					}
	      				else if(parsedData[0].equals("uneliminate")) {
						message.type = "gameAction";
						message.data = "uneliminate card";
						message.parameters.add(parsedData[1]);
					}
					else if(parsedData[0].equals("show")) {
	      					if(parsedData[1].equals("cards")) {
	      						message.type = "gameAction";
	      						message.data = "show cards";
	      					}
	      					if(parsedData[1].equals("dpad")) {
	      						message.type = "gameAction";
								message.data = "show detective pad";
						}
					}
	      				else if(parsedData[0].equals("end") && parsedData[1].equals("go")) {
	      					message.type = "gameAction";
				      		message.data = "end go";
	      				}	
				}
				if(parsedData.length == 3) {
	      				if(parsedData[0].equals("show")) {
	      					if(parsedData[1].equals("detective") && parsedData[2].equals("pad")) {
	      						message.type = "gameAction";
	      						message.data = "show detective pad";
						}
					}
	      			if(parsedData[0].equals("suggest")) {
  						message.type = "gameAction";
  						message.data = "suggest";
  						message.parameters.add(parsedData[1]);
  						message.parameters.add(parsedData[2]);
	      			}
				}
				if(parsedData.length == 4) {
						if(parsedData[0].equals("accuse")) {
  							message.type = "gameAction";
  							message.data = "accuse";
  							message.parameters.add(parsedData[1]);
  							message.parameters.add(parsedData[2]);
  							message.parameters.add(parsedData[3]);
	      				}
				}
				if(parsedData[0].equals("help")) {
					message.type = "showHelpFile";
					// dataArray - separator - offset
					message.data = StringFuncs.implode(parsedData, "_", 1);
				}
			}
	      		
	      		// NEW PLAYER CODE
	      		
	      		
	      		if(formingGame == true) {
	        		// ******************* Input handling for new game *******************
	        		// This is the only instance of this type of mutliple line input and tracking...
    				Message feedback = null;
	        		try {
	    				int tempNumber = 0;
	    				
	    				String imploded = StringFuncs.implode(parsedData);
	    				int allocatedPlayers = -1;
	    				int amountPlayers = -1;
	    				String lastName = "";
	    				
	    				allocatedPlayers = gameConfig.getAllocatedPlayers();
	    				
	    				if(allocatedPlayers == -1) {
	    					try {
	    						tempNumber = Integer.parseInt(parsedData[0]);
                		
	    						if(tempNumber >=3 && tempNumber <= 6) {
	    							gameConfig.setAmountPlayers(tempNumber);
                		
	    							feedback = new Message();
	    							feedback.type = "addNextPlayer";
	    							notifyListener(feedback);
	    						}
	    						else {
	    							feedback = new Message();
	    							feedback.type = "badGameSize";
	    							notifyListener(feedback);
	    						}
                		
	    					}
	    					catch(Exception ee) {
    							feedback = new Message();
    							feedback.type = "badGameSize";
    							notifyListener(feedback);
	    					}
	    				}
	    				else {
	    					
	    					// Reading each player now
                		
	    						allocatedPlayers = gameConfig.getAllocatedPlayers();
	    						amountPlayers = gameConfig.getAmountPlayers();
	    						
    	    					try {
    	    						boolean playerAccepted = false;
    	    						feedback = null;
   				    				StringTokenizer tokens = new StringTokenizer (parsedData[0], " " ); 
   				    				if(tokens.countTokens() == 2) {
   				    					String name = tokens.nextToken();
										String suspect = tokens.nextToken();
										
   				    					try {
   				    						Vector validNames = gameConfig.getValidCharacterNames();
   				    						int index = Integer.parseInt(suspect);
   				    						suspect = ((String)validNames.elementAt(index));
   				    					}
   				    					catch(Exception noConvert) {
                		
   				    					}
   				    					boolean wellFormedName = StringFuncs.validAlphaNumeric(name);
                		
   				    					if(wellFormedName == false || name.length() > 20) {
										feedback = new Message();
	    				    	    				feedback.type = "badNewPlayerFormat";
				    	    	    				notifyListener(feedback);
				    	    	    			}
   				    					else
										if(gameConfig.validCharacterName( suspect ) == true) {
											playerAccepted = gameConfig.addPlayer(name, suspect);
										}
   				    				}
								else {
									feedback = new Message();
	    				    	    			feedback.type = "badNewPlayer";
				    	    	    			notifyListener(feedback);
								}
								if(feedback == null) {
				    		    			if(playerAccepted == true) {
	    					    	    			feedback = new Message();
					    	    	    			feedback.type = "addedNewPlayer";
					    	    	    			notifyListener(feedback);
				    		    			}
				    		    			else {
				    	    		    			feedback = new Message();
				    		    	    			feedback.type = "badNewPlayer";
					    	    	    			notifyListener(feedback);
				    		    			}
								}
	    			    		}
    	    					catch(Exception general2) {
    	    						System.out.println("Can't add player");
    	    					}
    	    					
				    			allocatedPlayers = gameConfig.getAllocatedPlayers();
				    			amountPlayers = gameConfig.getAmountPlayers();
                		
	    						amountPlayers = gameConfig.getAmountPlayers();
                		
	    						if(allocatedPlayers == amountPlayers) {
	    			    			feedback = new Message();
									feedback.type = "startNewGame";
	    			    			notifyListener(feedback);
				    				gameConfig.setFormingGame(false);
	    						}
	    					}
	    			}
	    	       		catch(Exception general) {
					feedback = new Message();
					feedback.type = "textHandlerError";
					notifyListener(feedback);
	        		}    	    			
	      		// END NEW PLAYER CODE	    			
	    		}
	    		else if(disproveMode == true) {
				Message feedback = new Message();
				feedback.type = "disproveFeedback";
				feedback.data = parsedData[0];
				notifyListener(feedback);
				return;
	    		}
 		}

 	    catch(Exception general) {
	    	System.out.println("General exception in texthandler \n'" +general.getCause()+"'");
	    }

	    // Send an error message if command was unmatched.
	    if((message.type.equals("") && message.data.equals("")) && formingGame == false && disproveMode == false) {
                message.type = "errorInParameters";
                message.data = parsedData[0];
            }
            
	 notifyListener(message);
 }
  

}
